package com.zh.chat.net;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;
import net.sf.json.util.JSONUtils;

import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;

import com.zh.chat.entity.UDPProtocol;
import com.zh.chat.util.ConfigUtil;

/**
 * 网络服务类 一个socket用于收发命令 另一个socket用于检查用户是否在线
 * @author 逍遥の剑仙
 *
 */
public class UDPDTOImpl extends DTOBase implements UdpDTO {
	public static SimpleDateFormat sdf = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");
	private Logger log = Logger.getLogger(UDPDTOImpl.class);
	private Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
	private static JsonConfig jcfg = new JsonConfig();

	public UDPDTOImpl(ConfigUtil config) {
		super(config);
		init();
		log.info("UdpDTO初始化完成");
	}
	
	@Override
	public void requestIP() {
		UDPProtocol protocol = new UDPProtocol();
		protocol.setCode(UDPProtocol.REQ_IP);
		protocol.setServerIp(SERVER_IP);
		protocol.setServerPort(SERVER_PORT);
		protocol.setClientPort(CLIENT_RECV_PORT);
		protocol.setClientFilePort(TCP_PORT);
		protocol.setSendTime(new java.util.Date().getTime());
		JSONObject o = (JSONObject) JSONSerializer.toJSON(protocol, jcfg);
		String seri = o.toString();
		try {
			outBuf = seri.getBytes(CHARSET);// 编码方式UTF-8
			DatagramPacket dp = new DatagramPacket(outBuf, outBuf.length);
			dp.setAddress(InetAddress.getByName(protocol.getServerIp()));
			dp.setPort(protocol.getServerPort());// 设置此包的发送目的端口
			outSocket.send(dp);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void init() {
		try {
			this.inSocket = new DatagramSocket(CLIENT_RECV_PORT);// 监听端口
			this.outSocket = new DatagramSocket(CLIENT_SEND_PORT);// 发送数据的端口
		} catch (SocketException e) {
			log.error(e);
		}
		jcfg.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
		jcfg.registerJsonValueProcessor("birthday", new DateJsonValueProcessor(
				dateFormat));
		jcfg.registerJsonValueProcessor("registerDate",
				new DateJsonValueProcessor(timeFormat));
		jcfg.registerJsonValueProcessor("lastLoginDate",
				new DateJsonValueProcessor(timeFormat));
	}

	@Override
	public void close() {
		if (!inSocket.isClosed()) {
			inSocket.close();
			inSocket = null;
		}
		if (!outSocket.isClosed()) {
			outSocket.close();
			outSocket = null;
		}
	}

	@Override
	public com.zh.chat.entity.UDPProtocol recive(){
		UDPProtocol prot = null;
		inBuf = new byte[MAX_PACKET_SIZE];
		DatagramPacket dp = new DatagramPacket(inBuf, MAX_PACKET_SIZE);// 设置udp缓冲区
		try {
			inSocket.receive(dp);
		} catch (IOException e) {return null;}// 接收数据报
		int index = ArrayUtils.indexOf(inBuf, (byte) 0);// 找到字符串结尾
		inBuf = ArrayUtils.subarray(inBuf, 0, index);// 截取有用的字符串，删除后面的0
		
		String jsonStr = null;
		try {
			jsonStr = new String(inBuf, CHARSET);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}// 得到json字符串
		System.out.println("客户端收到"+jsonStr);
		JSONObject jsonObject = JSONObject.fromObject(jsonStr, jcfg);
		try {
			classMap.put("data", Class
					.forName((String) jsonObject.get("clazz")));
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		JSONUtils.getMorpherRegistry().registerMorpher(
				new DateMorpher(new String[] { timeFormat, dateFormat }));
		prot = (UDPProtocol) JSONObject.toBean(jsonObject, UDPProtocol.class, classMap);
		prot.setReciveTime(new java.util.Date().getTime());// 设置接收的时间
		return prot;
	}

	@Override
	public void send(com.zh.chat.entity.UDPProtocol protocol) throws IOException {
		protocol.setServerIp(SERVER_IP);
		protocol.setServerPort(SERVER_PORT);
		protocol.setClientIp(CLIENT_IP);
		protocol.setClientPort(CLIENT_RECV_PORT);
		protocol.setClientFilePort(TCP_PORT);
		protocol.setSendTime(new java.util.Date().getTime());
		JSONObject o = (JSONObject) JSONSerializer.toJSON(protocol, jcfg);
		String seri = o.toString();
System.out.println("客户端发送"+seri);
		outBuf = seri.getBytes(CHARSET);// 编码方式UTF-8
		DatagramPacket dp = new DatagramPacket(outBuf, outBuf.length);
		dp.setAddress(InetAddress.getByName(protocol.getServerIp()));
		dp.setPort(protocol.getServerPort());// 设置此包的发送目的端口
		outSocket.send(dp);
	}

	@Override
	public String getServerIp() {
		return SERVER_IP;
	}

	@Override
	public int getServerPort() {
		// TODO Auto-generated method stub
		return SERVER_PORT;
	}

	@Override
	public int getClientRecvPort() {
		// TODO Auto-generated method stub
		return CLIENT_RECV_PORT;
	}

	@Override
	public int getClientSendPort() {
		// TODO Auto-generated method stub
		return CLIENT_SEND_PORT;
	}

	@Override
	public String getClientIp() {
		return 	CLIENT_IP;
	}

	@Override
	public int getFileInPort() {
		return TCP_PORT;
	}
	
	@Override
	public void setClientIP(String ip) {
		this.CLIENT_IP = ip;
	}

	@Override
	public int getVOICE_IN_PORT() {
		return VOICE_IN_PORT;
	}
}